home *** CD-ROM | disk | FTP | other *** search
/ Scene 96 / Scene 96 International Edition (Zyklop Software) (Disc 2) (1997).iso / misc / coding / ct_xmp15 / xm2mxm.cpp < prev    next >
C/C++ Source or Header  |  1996-09-15  |  22KB  |  801 lines

  1. // XM 2 MXM converter, (c) 95/96 Niklas Beisert / pascal
  2.  
  3. #include <conio.h>
  4. #include <string.h>
  5. #include <io.h>
  6. #include <fcntl.h>
  7. #include <sys\stat.h>
  8. #include <stdlib.h>
  9.  
  10. unsigned char patbuf1[0x20000];
  11. unsigned long patofs[256];
  12. unsigned long insofs[128];
  13. unsigned char insreloc[256];
  14. struct
  15. {
  16.   unsigned long srcofs;
  17.   unsigned long dstofs;
  18.   unsigned long len;
  19.   unsigned long loopstart;
  20.   unsigned long loopend;
  21.   unsigned char type;
  22. } sampinfo[2048];
  23.  
  24. void writestrbool(int f, char *s, int b)
  25. {
  26.   write(f, s, strlen(s));
  27.   write(f, b?"=1\r\n":"=0\r\n", 4);
  28. }
  29.  
  30. void main(int argc, char **argv)
  31. {
  32.   cputs("  XM to MXM converter v1.5     (c) '95/96 Niklas Beisert / pascal\r\n\n");
  33.  
  34.   int i,j,k;
  35.  
  36.   char spath[_MAX_PATH];
  37.   char dpath[_MAX_PATH];
  38.   char ipath[_MAX_PATH];
  39.   *spath=0;
  40.   *dpath=0;
  41.   unsigned char pantype=0;
  42.   int dodelta=1;
  43.   int include=0;
  44.  
  45.   for (i=1; i<argc; i++)
  46.   {
  47.     if ((argv[i][0]=='/')||(argv[i][0]=='-'))
  48.     {
  49.       if ((argv[i][1]&~0x20)=='P')
  50.       {
  51.         pantype=argv[i][2]-'0';
  52.         if (pantype>5)
  53.         {
  54.           cputs("invalid panning type!\r\n");
  55.           return;
  56.         }
  57.       }
  58.       else
  59.       if ((argv[i][1]&~0x20)=='D')
  60.         dodelta=0;
  61.       else
  62.       if ((argv[i][1]&~0x20)=='I')
  63.         include=1;
  64.       else
  65.       {
  66.         cputs("invalid switch!\r\n");
  67.         return;
  68.       }
  69.     }
  70.     else
  71.     {
  72.       if (!*spath)
  73.         strcpy(spath, argv[i]);
  74.       else
  75.       if (!*dpath)
  76.         strcpy(dpath, argv[i]);
  77.       else
  78.       {
  79.         cputs("invalid parameter!\r\n");
  80.         return;
  81.       }
  82.     }
  83.   }
  84.  
  85.   if (!*spath)
  86.   {
  87.     cputs("xm2mxm [switches] source [dest]\r\n");
  88.     cputs(" switches:\r\n");
  89.     cputs("   -p0:   XM-panning (instruments) (default)\r\n");
  90.     cputs("   -p1:  MOD-panning (LRRLLRRL)\r\n");
  91.     cputs("   -p2:  MOD-panning (less extreme)\r\n");
  92.     cputs("   -p3:  S3M-panning (LRLRLRLR)\r\n");
  93.     cputs("   -p4:  S3M-panning (less extreme)\r\n");
  94.     cputs("   -p5:    0-panning (MMMMMMMM)\r\n");
  95.     cputs("    -d:  do not use delta value samples\r\n");
  96.     cputs("    -i:  generate effects include file\r\n");
  97.     return;
  98.   }
  99.  
  100.   char name[_MAX_FNAME];
  101.   char ext[_MAX_EXT];
  102.   char dir[_MAX_DIR];
  103.   char drive[_MAX_DRIVE];
  104.  
  105.   _splitpath(spath, drive, dir, name, ext);
  106.   if (!*ext)
  107.     strcpy(ext, ".xm");
  108.   _makepath(spath, drive, dir, name, ext);
  109.  
  110.   char name2[_MAX_FNAME];
  111.   _splitpath(dpath, drive, dir, name2, ext);
  112.   if (!*name2)
  113.     strcpy(name2, name);
  114.   if (!*ext)
  115.     strcpy(ext, ".mxm");
  116.   _makepath(dpath, drive, dir, name2, ext);
  117.   _makepath(ipath, drive, dir, name2, ".inc");
  118.  
  119.   int file=open(spath, O_RDONLY|O_BINARY);
  120.   if (file<0)
  121.   {
  122.     cputs("could not open input file\r\n");
  123.     return;
  124.   }
  125.  
  126.   struct
  127.   {
  128.     char sig[17];
  129.     char name[20];
  130.     char whythis1a;
  131.     char tracker[20];
  132.     unsigned short ver;
  133.     unsigned long hdrsize;
  134.   } head1;
  135.  
  136.   struct
  137.   {
  138.     unsigned short ordnum;
  139.     unsigned short restart;
  140.     unsigned short channum;
  141.     unsigned short patnum;
  142.     unsigned short insnum;
  143.     unsigned short freqtab;
  144.     unsigned short tempo;
  145.     unsigned short speed;
  146.     unsigned char ord[256];
  147.   } head2;
  148.  
  149.   read(file, &head1, sizeof(head1));
  150.   if (memcmp(head1.sig, "Extended Module: ", 17))
  151.     return;
  152.   if (head1.whythis1a!=0x1a)
  153.     return;
  154.   if (head1.ver<0x104)
  155.     return;
  156.   read(file, &head2, sizeof(head2));
  157.   lseek(file, sizeof(head1)+head1.hdrsize-4, SEEK_SET);
  158.  
  159.   int addcleanpat=0;
  160.   for (i=0; i<head2.ordnum; i++)
  161.     if (head2.ord[i]>=head2.patnum)
  162.     {
  163.       head2.ord[i]=head2.patnum;
  164.       addcleanpat=1;
  165.     }
  166.   memset(head2.ord+head2.ordnum, 0, 256-head2.ordnum);
  167.  
  168.   int wf=open(dpath, O_WRONLY|O_BINARY|O_TRUNC|O_CREAT, S_IREAD|S_IWRITE);
  169.   if (file<0)
  170.   {
  171.     cputs("could not open output file\r\n");
  172.     return;
  173.   }
  174.  
  175.   struct
  176.   {
  177.     unsigned long sig;
  178.     unsigned long ordnum;
  179.     unsigned long restart;
  180.     unsigned long channum;
  181.     unsigned long patnum;
  182.     unsigned long insnum;
  183.     unsigned char tempo;
  184.     unsigned char speed;
  185.     unsigned short opt;
  186.     unsigned long sampstart;
  187.     unsigned long samples8;
  188.     unsigned long samples16;
  189.     signed long lowpitch;
  190.     signed long highpitch;
  191.     unsigned char panpos[32];
  192.   } mxmhead;
  193.  
  194.   if (!head2.channum||!head2.ordnum||!head2.patnum)
  195.   {
  196.     cputs("no channels/orders/patterns\r\n");
  197.     return;
  198.   }
  199.   if (head2.restart>head2.ordnum)
  200.     head2.restart=0;
  201.   memset(&mxmhead, 0, sizeof(mxmhead));
  202.   mxmhead.sig=*(unsigned long*)"MXM\0";
  203.   mxmhead.ordnum=head2.ordnum;
  204.   mxmhead.restart=head2.restart;
  205.   mxmhead.channum=head2.channum;
  206.   mxmhead.insnum=head2.insnum;
  207.   mxmhead.patnum=head2.patnum+addcleanpat;
  208.   mxmhead.tempo=head2.tempo;
  209.   mxmhead.speed=head2.speed;
  210.   mxmhead.opt=(head2.freqtab&1)|(pantype?2:0)|(dodelta?4:0);
  211.   switch (pantype)
  212.   {
  213.   case 0: memcpy(mxmhead.panpos, "\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80", 32); break;
  214.   case 1: memcpy(mxmhead.panpos, "\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00", 32); break;
  215.   case 2: memcpy(mxmhead.panpos, "\x40\xC0\xC0\x40\x40\xC0\xC0\x40\x40\xC0\xC0\x40\x40\xC0\xC0\x40\x40\xC0\xC0\x40\x40\xC0\xC0\x40\x40\xC0\xC0\x40\x40\xC0\xC0\x40", 32); break;
  216.   case 3: memcpy(mxmhead.panpos, "\x00\xFF\x00\xFF\x00\xFF\x00\xFF\x00\xFF\x00\xFF\x00\xFF\x00\xFF\x00\xFF\x00\xFF\x00\xFF\x00\xFF\x00\xFF\x00\xFF\x00\xFF\x00\xFF", 32); break;
  217.   case 4: memcpy(mxmhead.panpos, "\x40\xC0\x40\xC0\x40\xC0\x40\xC0\x40\xC0\x40\xC0\x40\xC0\x40\xC0\x40\xC0\x40\xC0\x40\xC0\x40\xC0\x40\xC0\x40\xC0\x40\xC0\x40\xC0", 32); break;
  218.   case 5: memcpy(mxmhead.panpos, "\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80", 32); break;
  219.   }
  220.   if (head2.freqtab&1)
  221.   {
  222.     mxmhead.lowpitch=-72*256;
  223.     mxmhead.highpitch=96*256;
  224.   }
  225.   else
  226.   {
  227.     mxmhead.lowpitch=107;
  228.     mxmhead.highpitch=438272;
  229.   }
  230.  
  231.  
  232.   write(wf, &mxmhead, sizeof(mxmhead));
  233.   write(wf, &head2.ord, 256);
  234.   write(wf, &insofs, 512);
  235.   write(wf, &patofs, 1024);
  236.  
  237.   unsigned long patstartpos=tell(file);
  238.  
  239.   for (i=0; i<head2.patnum; i++)
  240.   {
  241.     struct
  242.     {
  243.       unsigned long len;
  244.       unsigned char ptype;
  245.       unsigned short rows;
  246.       unsigned short patdata;
  247.     } pathead;
  248.     read(file, &pathead, sizeof(pathead));
  249.     lseek(file, pathead.patdata+pathead.len-sizeof(pathead), SEEK_CUR);
  250.   }
  251.  
  252.   memset(insreloc, 0xFF, 256);
  253.   insreloc[0]=0;
  254.  
  255.   char useifx[5];
  256.   memset(useifx, 0, 5);
  257.   int sampnum=0;
  258.   int curins=0;
  259.   for (i=0; i<head2.insnum; i++)
  260.   {
  261.     struct
  262.     {
  263.       unsigned long size;
  264.       char name[22];
  265.       char type;
  266.       unsigned short samp;
  267.     } ins1;
  268.  
  269.     read(file, &ins1, sizeof(ins1));
  270.     if (!ins1.samp)
  271.     {
  272.       lseek(file, ins1.size-sizeof(ins1), SEEK_CUR);
  273.       continue;
  274.     }
  275.     struct
  276.     {
  277.       unsigned long shsize;
  278.       unsigned char snum[96];
  279.       unsigned short venv[12][2];
  280.       unsigned short penv[12][2];
  281.       unsigned char vnum, pnum;
  282.       unsigned char vsustain, vloops, vloope, psustain, ploops, ploope;
  283.       unsigned char vtype, ptype;
  284.       unsigned char vibtype, vibsweep, vibdepth, vibrate;
  285.       unsigned short volfade;
  286.       unsigned short res;
  287.     } ins2;
  288.     read(file, &ins2, sizeof(ins2));
  289.     lseek(file, ins1.size-sizeof(ins1)-sizeof(ins2), SEEK_CUR);
  290.  
  291.     struct
  292.     {
  293.       unsigned long sampnum;
  294.       unsigned char snum[96];
  295.       unsigned short volfade;
  296.       unsigned char vibtype, vibsweep, vibdepth, vibrate;
  297.       unsigned char vnum, vsustain, vloops, vloope;
  298.       unsigned short venv[12][2];
  299.       unsigned char pnum, psustain, ploops, ploope;
  300.       unsigned short penv[12][2];
  301.       unsigned char res[46];
  302.     } mxmins;
  303.  
  304.     struct
  305.     {
  306.       unsigned short gusstartl;
  307.       unsigned char gusstarth;
  308.       unsigned short gusloopstl;
  309.       unsigned char gusloopsth;
  310.       unsigned short gusloopendl;
  311.       unsigned char gusloopendh;
  312.       unsigned char gusmode;
  313.       unsigned char vol;
  314.       unsigned char pan;
  315.       unsigned short relpitch;
  316.       unsigned char res[2];
  317.     } mxmsamp[16];
  318.  
  319.     unsigned char sampreloc[16];
  320.     memset(sampreloc, 0xFF, 16);
  321.  
  322.     int cursmp=0;
  323.     for (j=0; j<ins1.samp; j++)
  324.     {
  325.       struct
  326.       {
  327.         unsigned long samplen;
  328.         unsigned long loopstart;
  329.         unsigned long looplen;
  330.         unsigned char vol;
  331.         signed char finetune;
  332.         unsigned char type;
  333.         unsigned char pan;
  334.         signed char relnote;
  335.         unsigned char res;
  336.         unsigned char name[22];
  337.       } samp;
  338.       read(file, &samp, sizeof(samp));
  339.       lseek(file, ins2.shsize-sizeof(samp), SEEK_CUR);
  340.       if (!samp.samplen)
  341.         continue;
  342.  
  343.       if (samp.loopstart>samp.samplen)
  344.         samp.type&=~3;
  345.  
  346.       if ((samp.loopstart+samp.looplen)>samp.samplen)
  347.         samp.looplen=samp.samplen-samp.loopstart;
  348.  
  349.       if (!samp.looplen)
  350.         samp.type&=~3;
  351.  
  352.       if ((samp.samplen>262*1024)&&(samp.type&16))
  353.       {
  354.         cputs("16 bit sample too long\r\n");
  355.         return;
  356.       }
  357.  
  358.       if ((samp.type&16)&&((samp.samplen|samp.loopstart|samp.looplen)&1))
  359.       {
  360.         cputs("16 bit sample point odd\r\n");
  361.         return;
  362.       }
  363.  
  364.       if (samp.samplen>1024*1024)
  365.       {
  366.         cputs("sample too long\r\n");
  367.         return;
  368.       }
  369.  
  370.       mxmsamp[cursmp].relpitch=samp.relnote*256+samp.finetune*2;
  371.       mxmsamp[cursmp].vol=samp.vol;
  372.       mxmsamp[cursmp].pan=samp.pan;
  373.       mxmsamp[cursmp].gusmode=((samp.type&16)?0x04:0x00)|((samp.type&3)?(((samp.type&3)==2)?0x18:0x08):0x00);
  374.       mxmsamp[cursmp].gusstartl=samp.samplen;
  375.       mxmsamp[cursmp].gusstarth=samp.samplen>>16;
  376.       mxmsamp[cursmp].gusloopstl=samp.loopstart;
  377.       mxmsamp[cursmp].gusloopsth=samp.loopstart>>16;
  378.       mxmsamp[cursmp].gusloopendl=samp.loopstart+samp.looplen;
  379.       mxmsamp[cursmp].gusloopendh=(samp.loopstart+samp.looplen)>>16;
  380.       memset(mxmsamp[cursmp].res, 0, sizeof(mxmsamp->res));
  381.       sampreloc[j]=cursmp++;
  382.       if (samp.type&16)
  383.         useifx[4]=1;
  384.     }
  385.     if (!cursmp)
  386.       continue;
  387.  
  388.     insofs[curins]=tell(wf);
  389.     insreloc[i+1]=++curins;
  390.  
  391.     memset(&mxmins, 0, sizeof(mxmins));
  392.     mxmins.sampnum=cursmp;
  393.     for (j=0; j<96; j++)
  394.       mxmins.snum[j]=sampreloc[ins2.snum[j]];
  395.     mxmins.volfade=0xFFFF;
  396.     mxmins.vnum=0;
  397.     mxmins.vsustain=0xFF;
  398.     mxmins.vloops=0;
  399.     mxmins.vloope=0xFF;
  400.     mxmins.venv[0][0]=0;
  401.     mxmins.venv[0][1]=64;
  402.     mxmins.pnum=0;
  403.     mxmins.psustain=0xFF;
  404.     mxmins.ploops=0;
  405.     mxmins.ploope=0xFF;
  406.     mxmins.penv[0][0]=0;
  407.     mxmins.penv[0][1]=32;
  408.     mxmins.volfade=ins2.volfade; // ??????????????????????????????????????
  409.     if (ins2.vtype&1)
  410.     {
  411.       useifx[0]=1;
  412.       mxmins.vnum=ins2.vnum-1;
  413.       for (j=0; j<mxmins.vnum; j++)
  414.       {
  415.         mxmins.venv[j][0]=ins2.venv[j+1][0]-ins2.venv[j][0];
  416.         mxmins.venv[j][1]=ins2.venv[j][1];
  417.       }
  418.       mxmins.venv[mxmins.vnum][0]=0;
  419.       mxmins.venv[mxmins.vnum][1]=ins2.venv[mxmins.vnum][1];
  420.       if (ins2.vtype&2)
  421.         mxmins.vsustain=ins2.vsustain;
  422.       if (ins2.vtype&4)
  423.       {
  424.         if (ins2.vloops<=ins2.vnum)
  425.           mxmins.vloops=ins2.vloops;
  426.         mxmins.vloope=ins2.vloope;
  427.       }
  428.       mxmins.volfade=ins2.volfade;
  429.     }
  430.     if (ins2.ptype&1)
  431.     {
  432.       useifx[1]=1;
  433.       mxmins.pnum=ins2.pnum-1;
  434.       for (j=0; j<mxmins.pnum; j++)
  435.       {
  436.         mxmins.penv[j][0]=ins2.penv[j+1][0]-ins2.penv[j][0];
  437.         mxmins.penv[j][1]=ins2.penv[j][1];
  438.       }
  439.       mxmins.penv[mxmins.pnum][0]=0;
  440.       mxmins.penv[mxmins.pnum][1]=ins2.penv[mxmins.pnum][1];
  441.       if (ins2.ptype&2)
  442.         mxmins.psustain=ins2.psustain;
  443.       if (ins2.ptype&4)
  444.       {
  445.         if (ins2.ploops<=ins2.pnum)
  446.           mxmins.ploops=ins2.ploops;
  447.         mxmins.ploope=ins2.ploope;
  448.       }
  449.     }
  450.     if (ins2.vibdepth)
  451.     {
  452.       useifx[2]=1;
  453.       if (ins2.vibtype!=0)
  454.         useifx[3]=1;
  455.       mxmins.vibtype=(ins2.vibtype==1)?2:(ins2.vibtype==2)?3:(ins2.vibtype==3)?1:0;
  456.       mxmins.vibsweep=ins2.vibsweep;
  457.       mxmins.vibdepth=ins2.vibdepth;
  458.       mxmins.vibrate=ins2.vibrate;
  459.     }
  460.     write(wf, &mxmins, sizeof(mxmins));
  461.  
  462.     for (j=0; j<cursmp; j++)
  463.     {
  464.       sampinfo[sampnum].srcofs=tell(file);
  465.       sampinfo[sampnum].dstofs=tell(wf);
  466.       sampinfo[sampnum].len=mxmsamp[j].gusstartl+(mxmsamp[j].gusstarth<<16);
  467.       sampinfo[sampnum].loopstart=mxmsamp[j].gusloopstl+(mxmsamp[j].gusloopsth<<16);
  468.       sampinfo[sampnum].loopend=mxmsamp[j].gusloopendl+(mxmsamp[j].gusloopendh<<16);
  469.       sampinfo[sampnum].type=mxmsamp[j].gusmode;
  470.       write(wf, &mxmsamp[j], sizeof(*mxmsamp));
  471.       lseek(file, sampinfo[sampnum].len, SEEK_CUR);
  472.       sampnum++;
  473.     }
  474.   }
  475.  
  476.   mxmhead.insnum=curins;
  477.   if (!curins)
  478.   {
  479.     cputs("no instruments\r\n");
  480.     return;
  481.   }
  482.  
  483.   lseek(file, patstartpos, SEEK_SET);
  484.  
  485.   char usefx[52];
  486.   char usevfx[52];
  487.   memset(usefx, 0, 52);
  488.   memset(usevfx, 0, 16);
  489.   for (i=0; i<head2.patnum; i++)
  490.   {
  491.     struct
  492.     {
  493.       unsigned long len;
  494.       unsigned char ptype;
  495.       unsigned short rows;
  496.       unsigned short patdata;
  497.     } pathead;
  498.     read(file, &pathead, sizeof(pathead));
  499.     lseek(file, pathead.len-sizeof(pathead), SEEK_CUR);
  500.  
  501.     read(file, patbuf1, pathead.patdata);
  502.     memset(patbuf1+pathead.patdata, 0x80, 0x10000-pathead.patdata);
  503.     unsigned char *pp1=patbuf1;
  504.     unsigned char *pp2=patbuf1+0x10000;
  505.     *(unsigned long*)pp2=pathead.rows;
  506.     pp2+=4;
  507.  
  508.     for (j=0; j<pathead.rows; j++)
  509.     {
  510.       for (k=0; k<head2.channum; k++)
  511.       {
  512.         unsigned char note=0;
  513.         unsigned char ins=0;
  514.         unsigned char vol=0;
  515.         unsigned char cmd=0;
  516.         unsigned char data=0;
  517.         unsigned char pack=*pp1++;
  518.         if (pack&0x80)
  519.         {
  520.           if (pack&0x01)
  521.             note=*pp1++;
  522.           if (pack&0x02)
  523.             ins=*pp1++;
  524.           if (pack&0x04)
  525.             vol=*pp1++;
  526.           if (pack&0x08)
  527.             cmd=*pp1++;
  528.           if (pack&0x10)
  529.             data=*pp1++;
  530.         }
  531.         else
  532.         {
  533.           note=pack;
  534.           ins=*pp1++;
  535.           vol=*pp1++;
  536.           cmd=*pp1++;
  537.           data=*pp1++;
  538.         }
  539.  
  540.         if (cmd>=36)
  541.           cmd=data=0;
  542.         if (cmd==0xE)
  543.         {
  544.           cmd=36+(data>>4);
  545.           data&=0xF;
  546.         }
  547.  
  548.         pack=0;
  549.         if (note||ins)
  550.           pack|=0x20;
  551.         if (vol)
  552.           pack|=0x40;
  553.         if (cmd||data)
  554.           pack|=0x80;
  555.         if (pack)
  556.         {
  557.           pack|=k;
  558.           *pp2++=pack;
  559.           if (pack&0x20)
  560.           {
  561.             *pp2++=note;
  562.             *pp2++=insreloc[ins];
  563.           }
  564.           if (pack&0x40)
  565.           {
  566.             *pp2++=vol;
  567.             usevfx[vol>>4]=1;
  568.           }
  569.           if (pack&0x80)
  570.           {
  571.             usefx[cmd]=1;
  572.             *pp2++=cmd;
  573.             *pp2++=data;
  574.           }
  575.         }
  576.       }
  577.       *pp2++=0;
  578.     }
  579.     patofs[i]=tell(wf);
  580.     write(wf, patbuf1+0x10000, pp2-patbuf1-0x10000);
  581.   }
  582.   if (addcleanpat)
  583.   {
  584.     patofs[head2.patnum]=tell(wf);
  585.     *patbuf1=64;
  586.     memset(patbuf1+1, 0, 67);
  587.     write(wf, patbuf1, 68);
  588.   }
  589.  
  590.   long memsize8=0;
  591.   long memsize16=0;
  592.  
  593.   for (i=0; i<sampnum; i++)
  594.   {
  595.     if (sampinfo[i].type&4)
  596.       memsize16+=(sampinfo[i].len>>1)+1;
  597.     else
  598.       memsize8+=sampinfo[i].len+1;
  599.   }
  600.   memsize8=(memsize8+15)&~15;
  601.   memsize16=(memsize16+7)&~7;
  602.   mxmhead.samples8=memsize8;
  603.   mxmhead.samples16=memsize16;
  604.   mxmhead.sampstart=tell(wf);
  605.  
  606.   if ((memsize8+2*memsize16)>1024*1024)
  607.   {
  608.     cputs("samples too long\r\n");
  609.     return;
  610.   }
  611.  
  612.   signed char *mem8=new signed char [memsize8];
  613.   memset(mem8, 0, memsize8);
  614.  
  615.   unsigned long guspos=0;
  616.   for (i=0; i<sampnum; i++)
  617.   {
  618.     if (sampinfo[i].type&4)
  619.       continue;
  620.     lseek(file, sampinfo[i].srcofs, SEEK_SET);
  621.     read(file, mem8+guspos, sampinfo[i].len);
  622.     signed char d=0;
  623.     for (j=0; j<sampinfo[i].len; j++)
  624.       mem8[guspos+j]=d+=mem8[guspos+j];
  625.  
  626.     lseek(wf, sampinfo[i].dstofs, SEEK_SET);
  627.     unsigned long b,a=guspos;
  628.     write(wf, &a, 3);
  629.     mem8[guspos+sampinfo[i].len]=mem8[guspos+sampinfo[i].len-1];
  630.     if (sampinfo[i].type&8)
  631.     {
  632.       b=a+sampinfo[i].loopstart;
  633.       write(wf, &b, 3);
  634.       b=a+sampinfo[i].loopend;
  635.       write(wf, &b, 3);
  636.       if (!(sampinfo[i].type&16))
  637.         mem8[guspos+sampinfo[i].loopend]=mem8[guspos+sampinfo[i].loopstart];
  638.     }
  639.     else
  640.     {
  641.       b=0;
  642.       write(wf, &b, 3);
  643.       b=a+sampinfo[i].len;
  644.       write(wf, &b, 3);
  645.     }
  646.  
  647.     guspos+=sampinfo[i].len+1;
  648.   }
  649.  
  650.   lseek(wf, 0, SEEK_END);
  651.  
  652.   if (dodelta)
  653.   {
  654.     signed char l=0;
  655.     for (i=0; i<memsize8; i++)
  656.     {
  657.       signed char delta=mem8[i]-l;
  658.       l=mem8[i];
  659.       mem8[i]=delta;
  660.     }
  661.   }
  662.   write(wf, mem8, memsize8);
  663.  
  664.   delete mem8;
  665.  
  666.   signed short *mem16=new signed short [memsize16];
  667.   memset(mem16, 0, memsize16*2);
  668.  
  669.   guspos=0;
  670.   for (i=0; i<sampnum; i++)
  671.   {
  672.     if (!(sampinfo[i].type&4))
  673.       continue;
  674.     sampinfo[i].loopstart>>=1;
  675.     sampinfo[i].loopend>>=1;
  676.     sampinfo[i].len>>=1;
  677.     lseek(file, sampinfo[i].srcofs, SEEK_SET);
  678.     read(file, mem16+guspos, sampinfo[i].len*2);
  679.     signed short d=0;
  680.     for (j=0; j<sampinfo[i].len; j++)
  681.       mem16[guspos+j]=d+=mem16[guspos+j];
  682.  
  683.     lseek(wf, sampinfo[i].dstofs, SEEK_SET);
  684.     unsigned long b,a=((guspos+(memsize8>>1))&0x1FFFF)|0x20000|(((guspos+(memsize8>>1))<<1)&0xC0000);
  685.     write(wf, &a, 3);
  686.     mem16[guspos+sampinfo[i].len]=mem16[guspos+sampinfo[i].len-1];
  687.     if (sampinfo[i].type&8)
  688.     {
  689.       b=a+sampinfo[i].loopstart;
  690.       write(wf, &b, 3);
  691.       b=a+sampinfo[i].loopend;
  692.       write(wf, &b, 3);
  693.       if (!(sampinfo[i].type&16))
  694.         mem16[guspos+sampinfo[i].loopend]=mem16[guspos+sampinfo[i].loopstart];
  695.     }
  696.     else
  697.     {
  698.       b=0;
  699.       write(wf, &b, 3);
  700.       b=a+sampinfo[i].len;
  701.       write(wf, &b, 3);
  702.     }
  703.  
  704.     guspos+=sampinfo[i].len+1;
  705.   }
  706.  
  707.   lseek(wf, 0, SEEK_END);
  708.  
  709.   if (dodelta)
  710.   {
  711.     signed short l16=0;
  712.     for (i=0; i<memsize16; i++)
  713.     {
  714.       signed short delta=mem16[i]-l16;
  715.       l16=mem16[i];
  716.       mem16[i]=delta;
  717.     }
  718.   }
  719.  
  720.   write(wf, mem16, memsize16*2);
  721.   delete mem16;
  722.  
  723.   lseek(wf, 0, SEEK_SET);
  724.   write(wf, &mxmhead, sizeof(mxmhead));
  725.   write(wf, &head2.ord, 256);
  726.   write(wf, &insofs, 512);
  727.   write(wf, &patofs, 1024);
  728.   lseek(wf, 0, SEEK_END);
  729.  
  730.   close(wf);
  731.   close(file);
  732.  
  733.   cputs(dpath);
  734.   cputs(" written\r\n");
  735.  
  736.   if (include)
  737.   {
  738.     wf=open(ipath, O_WRONLY|O_BINARY|O_CREAT|O_TRUNC, S_IREAD|S_IWRITE);
  739.     writestrbool(wf, "USEARPEGGIO", usefx[0]);
  740.     writestrbool(wf, "USEPORTA", usefx[1]||usefx[2]);
  741.     writestrbool(wf, "USEPORTANOTE", usefx[3]);
  742.     writestrbool(wf, "USEVIBRATO", usefx[4]);
  743.     writestrbool(wf, "USEPORTAVOL", usefx[5]);
  744.     writestrbool(wf, "USEVIBRATOVOL", usefx[6]);
  745.     writestrbool(wf, "USETREMOLO", usefx[7]);
  746.     writestrbool(wf, "USEPAN", usefx[8]);
  747.     writestrbool(wf, "USEOFFSET", usefx[9]);
  748.     writestrbool(wf, "USEVOLSLIDE", usefx[10]);
  749.     writestrbool(wf, "USEJUMP", usefx[11]);
  750.     writestrbool(wf, "USEVOL", usefx[12]);
  751.     writestrbool(wf, "USEBREAK", usefx[13]);
  752.     writestrbool(wf, "USESPEED", usefx[15]);
  753.     writestrbool(wf, "USEGVOL", usefx[16]);
  754.     writestrbool(wf, "USEGVOLSLIDE", usefx[17]);
  755.     writestrbool(wf, "USEKEYOFFCMD", usefx[20]);
  756.     writestrbool(wf, "USEENVPOS", usefx[21]);
  757.     writestrbool(wf, "USEPANSLIDE", usefx[25]);
  758.     writestrbool(wf, "USEMRETRIG", usefx[27]);
  759.     writestrbool(wf, "USESYNC", usefx[28]||usefx[36+15]);
  760.     writestrbool(wf, "USETREMOR", usefx[29]);
  761.     writestrbool(wf, "USEXFPORTA", usefx[33]);
  762.     writestrbool(wf, "USEFPORTA", usefx[36+1]||usefx[36+2]);
  763.     writestrbool(wf, "USEGLISSANDO", usefx[36+3]);
  764.     writestrbool(wf, "USEVIBTYPE", usefx[36+4]);
  765. //    writestrbool(wf, "USEFINETUNE", usefx[36+5]);
  766.     writestrbool(wf, "USEPATLOOP", usefx[36+6]);
  767.     writestrbool(wf, "USETREMTYPE", usefx[36+7]);
  768.     writestrbool(wf, "USESPAN", usefx[36+8]);
  769.     writestrbool(wf, "USERETRIG", usefx[36+9]);
  770.     writestrbool(wf, "USEFVOLSLIDE", usefx[36+10]||usefx[36+11]);
  771.     writestrbool(wf, "USENOTECUT", usefx[36+12]);
  772.     writestrbool(wf, "USEDELAY", usefx[36+13]);
  773.     writestrbool(wf, "USEPATDELAY", usefx[36+14]);
  774.     write(wf, "\r\n", 2);
  775.  
  776.     writestrbool(wf, "USEVVOL", usevfx[1]|usevfx[2]|usevfx[3]|usevfx[4]|usevfx[5]);
  777.     writestrbool(wf, "USEVVOLSLIDE", usevfx[6]|usevfx[7]);
  778.     writestrbool(wf, "USEVFVOLSLIDE", usevfx[8]|usevfx[9]);
  779.     writestrbool(wf, "USEVVIBRATE", usevfx[10]);
  780.     writestrbool(wf, "USEVVIBRATO", usevfx[11]);
  781.     writestrbool(wf, "USEVPAN", usevfx[12]);
  782.     writestrbool(wf, "USEVPANSLIDE", usevfx[13]|usevfx[14]);
  783.     writestrbool(wf, "USEVPORTANOTE", usevfx[15]);
  784.     write(wf, "\r\n", 2);
  785.  
  786.     writestrbool(wf, "USEVOLENV", useifx[0]);
  787.     writestrbool(wf, "USEPANENV", useifx[1]);
  788.     writestrbool(wf, "USEAUTOVIBRATO", useifx[2]);
  789.     writestrbool(wf, "USEAUTOVIBRATOTYPE", useifx[3]);
  790.     writestrbool(wf, "USE16BIT", useifx[4]);
  791.     write(wf, "\r\n", 2);
  792.  
  793.     writestrbool(wf, "USEDELTASAMP", dodelta);
  794.     writestrbool(wf, "USEFREQTAB", head2.freqtab&1);
  795.  
  796.     close(wf);
  797.     cputs(ipath);
  798.     cputs(" written\r\n");
  799.   }
  800. }
  801.